package generics;

import java.util.*;

import static net.mindview.util.Print.*;

//class Building {
//}
//
//class House extends Building {
//    private String location;
//    private Integer area;
//
//    public House() {
//        this.location=null;
//    }
//
//    public House(String location) {
//        this.location = location;
//    }
//
//    public House(String location, Integer area) {
//        this.location = location;
//        this.area = area;
//    }
//
//    @Override
//    public String toString() {
//        return "House"+((location==null)?"":" in "+location)+
//                ((area!=null)?(","+area+" sqft"):"");
//    }
//}

public class ClassTypeCapture21<T> {
    Class<?> kind;
    Map<String, Class<?>> map;

    public ClassTypeCapture21(Class<?> kind) {
        this.kind = kind;
    }

    public ClassTypeCapture21(Class<?> kind, Map<String, Class<?>> map) {
        this.kind = kind;
        this.map = map;
    }

    public boolean f(Object arg) {
        return kind.isInstance(arg);
    }

    public void addType(String typename, Class<?> kind) {
        map.put(typename, kind);
    }

    public Object createNew(String typename)
            throws IllegalAccessException, InstantiationException {
        if (map.containsKey(typename))
            return map.get(typename).newInstance();
        System.out.println(typename + " class not available");
        return null;
    }

    public static void main(String[] args) {
        ClassTypeCapture21<Building> ctt1 = new ClassTypeCapture21<Building>(Building.class);
        System.out.println(ctt1.f(new Building()));
        System.out.println(ctt1.f(new House()));
        ClassTypeCapture21<House> ctt2 = new ClassTypeCapture21<House>(House.class);
        System.out.println(ctt2.f(new Building()));
        System.out.println(ctt2.f(new House()));
        ClassTypeCapture21<Building> ct = new ClassTypeCapture21<>(Building.class, new HashMap<String, Class<?>>());
        ct.addType("House", House.class);
        ct.addType("Building", Building.class);
        System.out.println("ct.map = " + ct.map);
        try {
            Building b = (Building) ct.createNew("Building");
            House h = (House) ct.createNew("House");
            System.out.println("b.getClass().getName(): " + b.getClass().getName());
            System.out.println("h.getClass().getName(): " + h.getClass().getName());
            System.out.println("House h is istance House:" + (h instanceof Building));
            System.out.println("Building b is instance of Buiding: " + (b instanceof House));
            ct.createNew("String");
        } catch (IllegalAccessException e) {
            System.out.println("IllegealAccessException in main");
        } catch (InstantiationException e) {
            System.out.println("InstantiationException in main");
        }
    }
}
